﻿#include "wubi_scheme.h"
#include <algorithm>
#include "wubi_db.h"
#include "word_dict.h"

WubiSchemeMgr::WubiSchemeMgr(){
    _db = std::make_shared<WubiDb>();
    _word_dic = std::make_shared<WordDic>();
    _db_path =  "./mengyu_wubi.db";
    _can_worddic_work = false;
}

WubiSchemeMgr::~WubiSchemeMgr() = default;

bool WubiSchemeMgr::init(const std::string &db_path) {
    _db_path = db_path;
    if (!_db->initialize(_db_path)) {
        return false;
    }
    
    // 加载默认方案id
    auto current_scheme_id = _db->getDefaultScheme();
    if (current_scheme_id == 0) {
        // 如果没有默认方案，那就等用用户自己创建
        return true;
    }

    //加载方案信息
    if(!_db->getSchemeInfo(current_scheme_id,_current_scheme)){
        //这里没加载出方案，可能人为删了，将默认方案设为无
        current_scheme_id = 0;
        return _db->setDefaultScheme(0);
    }

    return reloadWordDic();
}

bool WubiSchemeMgr::release() {
    _db.reset();
    _word_dic->clear();
    _current_scheme.reset();
    _can_worddic_work = false;
    return true;
}

bool WubiSchemeMgr::getSchemes(std::vector<WubiBaseInfoPtr> &out_schemes){
    out_schemes.clear();
    return _db->getAllSchemes(out_schemes);
}

bool WubiSchemeMgr::getCodeTables(MengYuIDType scheme_id , std::vector<WubiBaseInfoPtr> &out_tables) {
    out_tables.clear();
    return _db->getCodeTables(scheme_id, out_tables);
}

MengYuIDType WubiSchemeMgr::createScheme(const std::string& name) {
    return  _db->createScheme(name);
}

bool WubiSchemeMgr::deleteScheme(MengYuIDType id) {
    if (!_db->deleteScheme(id)) return false;
    
   
    // 如果删除的是当前方案，重置当前方案ID
    if (id == _current_scheme.id) {
        _current_scheme.reset();
        _db->setDefaultScheme(0); // 重置数据库中的默认方案ID为0，表示没有默认方案
    }
    return true;
}

bool WubiSchemeMgr::updateScheme(MengYuIDType schemeId, const std::string& name, int candidateCount){
    return _db->updateScheme(schemeId, name, candidateCount);
}

bool WubiSchemeMgr::getSchemeInfo(MengYuIDType scheme_id, WubiBaseInfo &out_scheme){
    return _db->getSchemeInfo(scheme_id, out_scheme);
}

MengYuIDType WubiSchemeMgr::addCodeTable(MengYuIDType scheme_id, const std::string& name, const std::string& file_path) {
    // 先添加码表到数据库
    MengYuIDType newId  = _db->addCodeTable(scheme_id, name);
    if (newId == 0) return 0;

    // 再导入数据
    if(!_db->importCodeTableData(newId, {file_path})){
        //导入失败，删除码表
        _db->removeCodeTable(newId);
        return 0;
    }
    return newId;
}

bool WubiSchemeMgr::removeCodeTable(MengYuIDType scheme_id, MengYuIDType code_table_id) {
    // 删除数据库中的码表
    return _db->removeCodeTable(code_table_id);
}

MengYuIDType WubiSchemeMgr::getCurrentSchemeId() {
    return _current_scheme.id;
}

int WubiSchemeMgr::getCurrentCandidateCount(){
    return _current_scheme.candidate_count;
}

bool WubiSchemeMgr::setCurrentSchemeId(MengYuIDType id) {
    if (!_db->setDefaultScheme(id)) return false;
    _current_scheme.reset();
    //加载方案信息
    if(!_db->getSchemeInfo(id,_current_scheme)){
        return false;
    }
    return reloadWordDic();
}

bool WubiSchemeMgr::reloadWordDic() {
    if(_current_scheme.id == 0) return false; // 没有当前方案，无法加载

    _can_worddic_work = false; // 先设置为不可用，加载完后再设置为可用

    // 获取当前方案的所有码表数据
    std::vector<WubiBaseInfoPtr> codeTables;
    if (!_db->getCodeTables(_current_scheme.id, codeTables)) {
        return false;
    }
    
    _word_dic->clear();
    std::vector<std::pair<std::string, std::string>> data;
    // 加载每个启用码表的数据
    for (const auto& table : codeTables) {
        if (table->codetable_enable) {
            _db->getCodeTableData(table->id, data);
        }
    }
    _word_dic->setWords(data);
    _can_worddic_work = true; // 加载完成后设置为可用
    
    return true;
}

bool WubiSchemeMgr::getCandidateList(const std::string& code, std::vector<std::string>& out_list) {
    out_list.clear();
    if(_current_scheme.id == 0) return false; // 没有当前方案，无法加载
    if(!_can_worddic_work){
        return false; //还不能用
    }

    return _word_dic->getCandidateList(code, out_list);
}

//根据编码获取码表数据
bool WubiSchemeMgr::getCodeTableDataByCode(MengYuIDType codeTableId, const std::string &code, std::vector<WubiCodetableData> &out_data){
    return _db->getCodeTableDataByCode(codeTableId, code, out_data);
}

// 交换两的个码表词条的顺序
bool WubiSchemeMgr::swapCodeTableDataOrder(MengYuIDType codeTableId, MengYuIDType code_id1, MengYuIDType code_id2){
    return _db->swapCodeTableDataOrder(codeTableId, code_id1, code_id2);
}

bool WubiSchemeMgr::swapCodeTableOrder(MengYuIDType codeTableId1, MengYuIDType codeTableId2){
    return _db->swapCodeTableOrder(codeTableId1, codeTableId2);
}

MengYuIDType WubiSchemeMgr::addWord(MengYuIDType codeTableId, const std::string& code, const std::string& word){
    return _db->addWord(codeTableId, code, word);
}
bool WubiSchemeMgr::removeWord(MengYuIDType code_id){
    return _db->removeWord(code_id);
}

bool WubiSchemeMgr::setCodeTableEnable(MengYuIDType codeTableId, bool enable){
    return _db->setCodeTableEnable(codeTableId, enable);
}

//编码反查，根据词获取所有启用码表的编码,
bool WubiSchemeMgr::getCodeByWord(const std::string &word,std::vector<std::string> &out_codes){
    if(_current_scheme.id == 0) return false; // 没有当前方案，无法加载
    if(word.empty()) return false; // 词为空，无法查询
    return _db->getCodeByWord(_current_scheme.id, word, out_codes); // 直接调用数据库方法，返回码表i
}

//导出码表
bool WubiSchemeMgr::exportCodeTable(MengYuIDType codeTableId, const std::string &file_path){
    if(codeTableId == 0) return false; // 没有当前方案，无法加载
    if(file_path.empty()) return false; // 词为空，无法查询
    return _db->exportCodeTable(codeTableId, file_path); // 直接调用数据库方法，返回码表i
}